package com.tanhua.manage.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.manage.mapper.UserFreezeMapper;
import com.tanhua.manage.mapper.UserInfoMapper;
import com.tanhua.manage.mapper.UserMapper;
import com.tanhua.manage.pojo.User;
import com.tanhua.manage.pojo.UserFreeze;
import com.tanhua.manage.pojo.UserInfo;
import com.tanhua.manage.pojo.UserLike;
import com.tanhua.manage.vo.PageResult;
import com.tanhua.manage.vo.UserInfoVo;
import com.tanhua.manage.vo.UserListVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class UserManageService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserFreezeMapper userFreezeMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    //冻结账户存储在Redis中key的前缀
    private static final String FREEZE_USER_REDIS_KEY_PREFIX = "FREEZE_USER_";





    /**
     * 查询用户列表
     *
     * @param page     页码
     * @param pageSize 页大小
     * @param userId   用户id         模糊查询时候用
     * @param nickName 昵称           模糊查询时候用
     * @param city     城市           模糊查询时候用
     * @return
     */
    public PageResult queryUsers(Integer page, Integer pageSize, String userId, String nickName, String city) {

        //验证用户

        PageResult pageResult = new PageResult();

        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        //构造查询 数据库层查询
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();

        if (StrUtil.isNotEmpty(userId)){
            wrapper.like("user_id",userId);
        }
        if (StrUtil.isNotEmpty(nickName)){
            wrapper.like("nick_name",nickName);
        }
        if (StrUtil.isNotEmpty(city)){
            wrapper.like("city",city);
        }

        List<UserInfo> userInfos = this.userInfoMapper.selectList(wrapper);


        ArrayList<UserListVo> userInfoVos = new ArrayList<>();


        for (UserInfo userInfo : userInfos) {

            UserListVo userListVo = new UserListVo();

            userListVo.setId(userInfo.getUserId());
            userListVo.setNickName(userInfo.getNickName());
            userListVo.setSex(userInfo.getSex().getValue()==1?"男":"女");
            userListVo.setCity(userInfo.getCity());
            userListVo.setUserStatus(this.isFreeze(userInfo.getUserId())?"冻结":"正常");
            userListVo.setLastActiveTime(123);// TODO 设置最近活跃时间


            userInfoVos.add(userListVo);


        }


        pageResult.setItems(userInfoVos);

        return pageResult;
    }

    /**
     * 查询该账户是否被冻结
     * @param userId
     * @return
     */
    public Boolean isFreeze(Long userId) {

        try {
            //判断redis中是否有数据  命中直接返回
            String redisKey = FREEZE_USER_REDIS_KEY_PREFIX+ userId;
            String data = redisTemplate.opsForValue().get(redisKey);
            if (StrUtil.isNotEmpty(data)) {
                return true;
            }

            //要是redis没有 去mysql中查询
            QueryWrapper<UserFreeze> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            UserFreeze userFreeze = this.userFreezeMapper.selectOne(wrapper);

            if (ObjectUtil.isNotEmpty(userFreeze)){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;

    }

    /**
     * 查询用户基本信息 构建vo对象
     * @param userId
     * @return
     */
    public UserInfoVo queryUserInfo(String userId) {

        //验证用户


        //  未知的:个性签名 最近活跃时间 最近登陆地  用户状态  职业(无字段 忽略)
        //  mongodb: 被喜欢人数 ,喜欢人数,配对数
        //查询    user_info表中id,昵称,性别,收入,注册地区,注册时间,头像,标签

        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        UserInfo userInfo = this.userInfoMapper.selectOne(wrapper);

        // user表: 手机号
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();

        wrapper2.eq("id",userId);

        User user = this.userMapper.selectOne(wrapper2);

        String mobile = user.getMobile();

        String keyMoblie = StrUtil.replace(mobile, 3, 7, '*');

        //  mongodb: 被喜欢人数 ,喜欢人数,配对数
        //喜欢人数
        Query query = Query.query(Criteria.where("userId").is(userId));
        long likedCount = this.mongoTemplate.count(query, UserLike.class);

        //被喜欢人数
        Query query2 = Query.query(Criteria.where("likeUser").is(userId));
        long beLikedCount = this.mongoTemplate.count(query2, UserLike.class);

        //配对数
        Long matchingCount = this.queryMutualLikeCount(Long.valueOf(userId));

        //构建vo对象
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setId(Integer.valueOf(userId));
        userInfoVo.setNickname(userInfo.getNickName());
        userInfoVo.setMoblie(keyMoblie);
        userInfoVo.setSex(userInfo.getSex().getValue()==1?"男":"女");
        userInfoVo.setAge(userInfo.getAge());

        userInfoVo.setCountBeLiked(Convert.toInt(beLikedCount));
        userInfoVo.setCountLiked(Convert.toInt(likedCount));
        userInfoVo.setCountMatching(Convert.toInt(matchingCount));

        userInfoVo.setOccupation("无");//职业:无
        userInfoVo.setCity(userInfo.getCity());//注册时间
        userInfoVo.setCreated(Convert.toInt(userInfo.getCreated()));//注册时间
        userInfoVo.setIncome(Convert.toInt(userInfo.getIncome()));
        userInfoVo.setUserStatus(this.isFreeze(userInfo.getUserId())?"冻结":"正常");
        userInfoVo.setLogo(userInfo.getLogo());
        userInfoVo.setTags(userInfo.getTags());

        userInfoVo.setPersonalSignature("无");//个人签名

        userInfoVo.setLastActiveTime(123);//TODO 最近活跃时间
        userInfoVo.setLateLoginLocation("最近登录地区");//TODO 最近登录地

        return userInfoVo;
    }

    /**
     * 冻结
     * @param userFreeze
     * @return
     */
    public Boolean freezeUser(UserFreeze userFreeze) {

        Long userId = userFreeze.getUserId();

        //判断是否冻结过了 如果冻结过了返回false
        Boolean result = this.isFreeze(userId);

        if (result) {

            return false;
        }

        //没有冻结 在冻结表中插入一条数据
        int num = this.userFreezeMapper.insert(userFreeze);

        String redisKey = FREEZE_USER_REDIS_KEY_PREFIX +userId;

        String hashKey = userFreeze.getFreezingRange().toString();

        String hashValue = userFreeze.getFreezingTime().toString();

        HashMap<String, String> map = new HashMap<>();
        map.put(hashKey,hashValue);

        if (num==1) {
            //插入成功 //更新redis中的数据
            /**
             *   key                value
             * 前缀_id         0冻结范围:1(冻结时间) "0:1"
             */
            this.redisTemplate.opsForValue().set(redisKey,map.toString(), Duration.ofHours(2));

            return true;
        }

        return false;
    }

    /**
     * 解冻
     * @param userId
     * @param reasonsForThawing
     * @return
     */
    public Boolean unfreezeUser(String userId, String reasonsForThawing) {

        //判断是否解冻过了 如果已经解冻过了返回false
        Boolean result = this.isFreeze(Convert.toLong(userId));

        if (!result) {

            return false;
        }

        //没有解冻 在冻结表中删除一条数据
        QueryWrapper<UserFreeze> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        int num = this.userFreezeMapper.delete(wrapper);


        String redisKey = FREEZE_USER_REDIS_KEY_PREFIX +userId;


        if (num==1) {
            //插入成功 //更新redis中的数据
            /**
             *   key                value
             * 前缀_id         0冻结范围:1(冻结时间)
             */
            this.redisTemplate.delete(redisKey);

            return true;
        }

        return false;

    }

    /**
     * 查询相互喜欢数
     * @param userId
     * @return
     */
    public Long queryMutualLikeCount(Long userId) {

        List<UserLike> userLikeList = this.mongoTemplate.find(Query.query(Criteria.where("userId")
                .is(userId)), UserLike.class);

        Long count = 0L;

        List<Object> likeUserIds = CollUtil.getFieldValues(userLikeList, "likeUserId");

        for (Object likeUserId : likeUserIds) {

            long num = this.mongoTemplate.count(Query.query(Criteria.where("userId").is(likeUserId).and("likeUserId").is(userId)), UserLike.class);

            if (num == 1) {

              count++;

            }

        }

        return count;

    }


}
